package com.seestech.sell.web.agent;

import com.alibaba.fastjson.JSONArray;
import com.github.pagehelper.Page;
import com.seestech.sell.common.annotation.RecordLog;
import com.seestech.sell.common.config.ApplicationConfig;
import com.seestech.sell.common.threads.AgentsDataBatchThread;
import com.seestech.sell.common.utils.*;
import com.seestech.sell.domain.model.*;
import com.seestech.sell.domain.model.enums.CodeEnums;
import com.seestech.sell.domain.model.enums.ExcelTypeEnums;
import com.seestech.sell.domain.model.enums.StatusEnums;
import com.seestech.sell.domain.model.vo.AgentVoExcel;
import com.seestech.sell.service.*;
import com.seestech.sell.web.SuperController;
import org.apache.commons.lang.StringUtils;
import org.apache.ibatis.session.RowBounds;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.annotation.Resource;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.*;

import static com.seestech.sell.common.utils.FileUtils.convert;
import static java.awt.SystemColor.info;
import static org.apache.coyote.http11.Constants.a;

/**
 * Created by idiot on 2017/6/19.
 */
@Controller
@RequestMapping(value = "agent/agentList")
public class AgentController extends SuperController {
    private static Logger logger = LoggerFactory.getLogger(AgentController.class);

    //文件名
    private static String fileName = "agent_template.xlsx";
    private static String agentListFile = "agent_list.xlsx";

    @Resource
    private IAgentService agentService;
    @Resource
    private IAgentGroupService agentGroupService;
    @Resource
    private IAgentTaskService agentTaskService;
    @Resource
    private IShelfService shelfService;
    @Resource
    private IAreaService areaService;
    @Resource
    private ApplicationConfig applicationConfig;

    //加载终端列表页面
    @RecordLog(value = "加载终端列表页面")
    @RequiresPermissions("agent:agentList:page")
    @RequestMapping(value = "page", method = RequestMethod.GET)
    public String toPage(){
        return "agent/agentList/page";
    }

    //加载data页面
    @RequestMapping(value = "data", method = RequestMethod.POST)
    public String data(Model model, Integer pageNo, @RequestParam(defaultValue="10")Integer pageSize, Agent info){
        //从数据库获取终端列表信息
        User user = getUser();
        if(user != null){
            info.setUserId(user.getUserId());
            List<Agent> list = agentService.getAllAgentsByUserId(new RowBounds((pageNo-1)*pageSize, pageSize), info);
            model.addAttribute("lists",list);
        }
        return "agent/agentList/data";
    }

    /**
     * 数据导出
     * @param model
     * @param info
     * @return
     * @throws FileNotFoundException
     */
    @ResponseBody
    @RequestMapping(value = "exportData.json", method = RequestMethod.POST)
    public String exportData(Model model, Agent info) throws FileNotFoundException {
        //项目访问路径
        String serverPath = request_local.get().getScheme() + "://" + request_local.get().getServerName() + ":" +
                request_local.get().getServerPort() + request_local.get().getContextPath() + "/";
        //从数据库获取终端列表信息
        User user = getUser();
        if(user != null){
            info.setUserId(user.getUserId());
            List<AgentVoExcel> list = agentService.getAllExportAgentsByUserId(new RowBounds(), info);
            // 写入excel文件
            File file = new File(Thread.currentThread().getContextClassLoader().getResource("/templates").getPath()+ agentListFile);
            OutputStream  out = new FileOutputStream(file);
            ExcelExport.exportExcel("终端列表", AgentVoExcel.class, list, out, ExcelTypeEnums.XLSX);
            //返回下载文件地址
            return ResponseUtils.responseSuccess(serverPath + agentListFile);
        }
        return ResponseUtils.responseError("用户信息已经失效，请重新登录");
    }

    //加载终端编辑页面
    @RequestMapping(value = "toUpdate", method = RequestMethod.GET)
    public String toAdd(Model model){
        User user = getUser();
        if(user == null){
            logger.error("获取信息======>>>>>>>>用户信息失效，请重新登录");
            return "login";
        }
        //货架信息
        Shelf shelf = new Shelf();
        //获取这个用户所在企业相关的用户信息
        Set<Long> userIds_shelf = getUserIds(user);
        userIds_shelf.add(user.getUserId());
        shelf.setUserIds(userIds_shelf);
        shelf.setCreateUser(null);
        shelf.setStatus(StatusEnums.VALID.getValue());
        List<Shelf> shelfs = shelfService.getShelfs(shelf);
        model.addAttribute("shelfs", shelfs);

        //区域信息
        Area area = new Area();
        //获取这个用户所在企业相关的用户信息
        Set<Long> userIds_area = getUserIds(user);
        userIds_area.add(user.getUserId());
        area.setUserIds(userIds_area);
        area.setCreateUser(null);
        area.setStatus(StatusEnums.VALID.getValue());
        List<Area> areas = areaService.getAreas(area);
        model.addAttribute("areas", areas);

        List<AgentGroup> agentGroups = agentGroupService.getAllValidAgentGroupsByUserId(user.getUserId());
        model.addAttribute("agentGroups", agentGroups);

        return "agent/agentList/update";
    }

    //编辑终端信息
    @RecordLog(value = "修改终端信息")
    @RequestMapping(value = "update", method = RequestMethod.POST)
    public void update(Agent info){
        //先判断终端编号是否存在
        if(info.getAgentCode() == null)
            ResponseUtils.writeErrorResponse(request_local.get(), response_local.get(), "无效的终端编号");
        //agentId为空/0时表示   新增操作
        if(info.getAgentId() == null){
            Agent agent = agentService.getAgentByAgentCode(info.getAgentCode());
            if(agent != null) {
                ResponseUtils.writeErrorResponse(request_local.get(), response_local.get(), "编辑终端失败，终端编号已经存在");
                return;
            }
            info.setAgentId(IdGen.get().nextId());  //设置主键
            info.setCreateUser(getUser().getUserId());
            info.setOnlineStatus(1); //设置终端当天断线
            agentService.insert(info);
            ResponseUtils.writeSuccessResponse(request_local.get(), response_local.get(), "新增终端信息成功");
        }else {     //修改操作
            List<Agent> agents = agentService.getAgentsByAgentCode(info.getAgentCode());
            if(agents != null && agents.size() == 1) {
                //获取第一个  判断主键是否相同  相同就允许修改
                Agent agent = agents.get(0);
                if(!agent.getAgentId().equals(info.getAgentId())) {
                    ResponseUtils.writeErrorResponse(request_local.get(), response_local.get(), "编辑终端失败，终端编号已经存在");
                    return;
                }
            }else if(agents != null && agents.size() > 1){
                ResponseUtils.writeErrorResponse(request_local.get(), response_local.get(), "编辑终端失败，终端编号已经存在");
                return;
            }
            info.setUpdateUser(getUser().getUserId());
            agentService.update(info);
            info = agentService.getAgentByAgentId(info.getAgentId());
            //如果终端是安卓  添加执行码5任务
            // if(info.getOs() == 3){
                AgentTaskInfo agentTaskInfo = new AgentTaskInfo();
                agentTaskInfo.setAgentCode(info.getAgentCode());
                agentTaskInfo.setCode(CodeEnums.five.getValue());
                agentTaskInfo.setCreateUser(getUser().getUserId());
                agentTaskService.insert(agentTaskInfo);
            // }
            ResponseUtils.writeSuccessResponse(request_local.get(), response_local.get(), "修改终端信息成功");
        }
    }

    //加载编辑页面
    @RequestMapping(value = "{agentId}/toUpdate", method = RequestMethod.GET)
    public String toUpdate(@PathVariable("agentId") long agentId, Model model){
        //货架信息
        Shelf info = new Shelf();
        info.setStatus(StatusEnums.VALID.getValue());
        List<Shelf> shelfs = shelfService.getShelfs(info);
        model.addAttribute("shelfs", shelfs);

        //区域信息
        Area area = new Area();
        area.setStatus(StatusEnums.VALID.getValue());
        List<Area> areas = areaService.getAreas(area);
        model.addAttribute("areas", areas);

        //获取终端信息
        Agent agent = agentService.getAgentByAgentId(agentId);
        model.addAttribute("agent",agent);

        User user = getUser();
        if(user != null){
            List<AgentGroup> agentGroups = agentGroupService.getAllValidAgentGroupsByUserId(user.getUserId());
            model.addAttribute("agentGroups", agentGroups);
        }
        return "agent/agentList/update";
    }

    //下载excel模板页面
    @RequestMapping(value = "toDownload", method = RequestMethod.GET)
    public String toDownload(Model model){
        //项目访问路径
        String serverPath = request_local.get().getScheme() + "://" + request_local.get().getServerName() + ":" +
                request_local.get().getServerPort() + request_local.get().getContextPath() + "/";
        //判断当前classpath下templates 目录中是否存在 fileName  文件  存在就返回下载路径
        File file = new File(Thread.currentThread().getContextClassLoader().getResource("/templates").getPath()+ fileName);
        if(file.exists()){
            model.addAttribute("filePath", serverPath + fileName);
        }
        return "agent/agentList/download";
    }

    //获取待下载的excel模板数据  返回excel下载地址
    @ResponseBody
    @RequestMapping(value = "download", method = RequestMethod.POST)
    public String download(AgentVoExcel agentVo) throws FileNotFoundException {
        //项目访问路径
        String serverPath = request_local.get().getScheme() + "://" + request_local.get().getServerName() + ":" +
                request_local.get().getServerPort() + request_local.get().getContextPath() + "/";
        // 获取数据   组装集合
        List<AgentVoExcel> list = new ArrayList<>();
        list.add(agentVo);
        // 写入excel文件
        File file = new File(Thread.currentThread().getContextClassLoader().getResource("/templates").getPath()+ fileName);
        OutputStream  out = new FileOutputStream(file);
        ExcelExport.exportExcel("模板数据", AgentVoExcel.class, list, out, ExcelTypeEnums.XLSX);
        // 返回下载地址
        String path = serverPath + fileName;
        return ResponseUtils.responseSuccess(path);
    }

    //删除终端信息
    @RecordLog(value = "删除终端信息")
    @RequestMapping(value = "{agentId}/delete", method = RequestMethod.POST)
    public void delete(@PathVariable("agentId") long agentId){
        agentService.delete(agentId);
        ResponseUtils.writeSuccessResponse(request_local.get(), response_local.get(),"删除终端信息成功");
    }

    //批量删除
    @RequestMapping(value = "deleteBatch", method = RequestMethod.POST)
    public void deleteBatch(@RequestParam("ids[]") Long[] agentIds){
        agentService.deleteBatch(agentIds);
        ResponseUtils.writeSuccessResponse(request_local.get(), response_local.get(), "批量删除终端信息成功");
    }


    /**
     * 加载终端信息接口
     * @param pageNo
     * @param pageSize
     * @param info
     * @return
     */
    @RequestMapping(value = "getUserAgents.json")
    @ResponseBody
    public Object getUserAgents(Integer pageNo, @RequestParam(defaultValue="10")Integer pageSize, Agent info){
        logger.info("加载终端信息接口");
        //从数据库获取终端列表信息
        ResultBean<Agent> resultBean = new ResultBean<>();
        User user = getUser();
        if(user != null){
            info.setUserId(user.getUserId());
            Page<Agent> list = agentService.getAllAgentsByUserId(new RowBounds((pageNo-1)*pageSize, pageSize), info);
            //json 过滤  long类型
            JSONArray object = JsonUtils.parseArray(list);
            resultBean = ResponseUtils.initResultBean(object, Constants.ResponseCode.success, "成功", true);
            resultBean.setTotalCount(list == null ? 0 :(int) list.getTotal());
        }
        return resultBean;
    }

    /**
     * @description  发送命令接口
     * @param agentId
     * @param code        命令
     * @return
     */
    @RequestMapping(value = "sendOrder.json")
    @ResponseBody
    public Object sendOrder(Long agentId, int code){
        String result;
        logger.info("======>>>>>发送命令接口======>>>>>【开始】");
        //检测用户是否失效
        User user = getUser();
        if(user == null){
            logger.error("======>>>>>发送命令接口======>>>>>【用户信息已失效】");
            return ResponseUtils.responseError("用户信息已失效，请重新登录");
        }
        //检测终端是否存在
        Agent agent = agentService.getAgentByAgentId(agentId);
        if(agent == null){
            logger.error("======>>>>>发送命令接口======>>>>>【无效的终端信息】");
            return ResponseUtils.responseError("终端信息有误");
        }
        //检测code是否有效
        if(CodeEnums.checkValue(code)){
            logger.info("======>>>>>发送命令接口======>>>>>【code】="+CodeEnums.getNameByValue(code));
            AgentTaskInfo info = new AgentTaskInfo();
            info.setAgentCode(agent.getAgentCode());
            info.setCode(code);                     //命令类型
            info.setCreateUser(user.getUserId());
            agentTaskService.insert(info);
            result = ResponseUtils.responseSuccess("发送命令成功");
        }else {
            logger.error("======>>>>>发送命令接口======>>>>>【无效的命令】"+code);
            result = ResponseUtils.responseError("无效的命令");
        }
        logger.info("======>>>>>发送命令接口======>>>>>【结束】");
        return result;
    }

    /**
     * @description  上传终端初始化图片
     * @param key  文件的name属性
     */
    @PostMapping(value = "uploadImage")
    public void uploadInitImage(String key){
        logger.info("上传终端初始化图片============>>>>>>开始");
        String result = uploadImage(applicationConfig, FileUtils.addPathSeparate(Constants.Regular.monitor_wall, Constants.Regular.agent_pictures), key);
        if(result != null && !"".equals(result))
            ResponseUtils.writeSuccessResponse(request_local.get(), response_local.get(), result);
        else
            ResponseUtils.writeErrorResponse(request_local.get(), response_local.get(), "上传失败");
    }

    /**
     * 上传excel   解析数据
     * @param multipartHttpServletRequest
     * @return   返回集合数据
     */
    @ResponseBody
    @RequestMapping(value = "uploadExcel", method = RequestMethod.POST)
    public Object uploadExcel(MultipartHttpServletRequest multipartHttpServletRequest){
        User user = getUser();
        if (user == null){
            return ResponseUtils.responseError("用户信息已经失效，请重新登录");
        }
        // 获取上传的文件
        Iterator<String> iterator = multipartHttpServletRequest.getFileNames();
        if(iterator.hasNext()) {    //不用遍历  每次取出一个
            MultipartFile multipartFile = multipartHttpServletRequest.getFile(iterator.next());
            if(multipartFile != null){
                String fileName = multipartFile.getOriginalFilename();  //文件名
                String extName = FileUtils.getExtName(fileName);        //获取文件拓展名
                // 校验是否是excel
                if(extName != null && ("xls".equals(extName) || "xlsx".equals(extName))){
                    // 存储文件   可以直接转换类型  File  之后删除即可
                    File file = convert(multipartFile);  //multipartFile 转 file
                    // 读取存储之后的文件   封装成集合
                    List<AgentVoExcel> list = null;
                    if ("xls".equals(extName)){
                        list = (List<AgentVoExcel>) ExcelImport.importExcel(file, AgentVoExcel.class, ExcelTypeEnums.XLS);
                    }else {
                        list = (List<AgentVoExcel>) ExcelImport.importExcel(file, AgentVoExcel.class, ExcelTypeEnums.XLSX);
                    }
                    if (list == null){
                        return ResponseUtils.responseError("列表数据不能为空");
                    }
                    FileUtils.deleteFile(file);     //删除磁盘的文件
                    //现有的终端
                    List<Agent> agents = agentService.getAllAgents(new Agent());
                    // 遍历数据   判断是否有效
                    for (int i = 0; i < list.size(); i++){
                        // 设置终端编号  创建时间
                        AgentVoExcel agentVo = list.get(i);
                        agentVo.setAgentId(IdGen.get().nextId());
                        agentVo.setCreateTime(new Date());
                        agentVo.setCreateUser(user.getUserId());

                        // 遍历现有的终端数据  检测agentCode 是否已经被占用
                        for (Agent agent : agents){
                            if(StringUtils.isEmpty(agentVo.getAgentCode()) || agent.getAgentCode().equals(agentVo.getAgentCode())){
                               list.remove(i);
                                i--;
                                break;
                            }
                        }
                    }
                    //如果数据不为空
                    if(list != null && list.size() > 0){
                        // 往线程  插入数据   返回结果  与提示信息
                        AgentsDataBatchThread.addCollectionData(list);
                        return ResponseUtils.responseSuccess("插入数据中，请稍后下载数据分析，总计"+list.size()+"条");
                    }
                    return ResponseUtils.responseError("数据无效，终端编号已经被占用，更新后重试");
                }
            }
        }
        return ResponseUtils.responseError("请参照模板数据上传excel文件");
    }

}
